/**
 * 如基本的单向加密算法：
 *    BASE64 严格地说，属于编码格式，而非加密算法
 *    MD5(Message Digest algorithm 5，信息摘要算法)
 *    SHA(Secure Hash Algorithm，安全散列算法)
 *    HMAC(Hash Message Authentication Code，散列消息鉴别码)
 *    
 * 复杂的对称加密（DES、PBE）、非对称加密算法：
 *    DES(Data Encryption Standard，数据加密算法)
 *    PBE(Password-based encryption，基于密码验证)
 *    RSA(算法的名字以发明者的名字命名：Ron Rivest, AdiShamir 和Leonard Adleman)
 *    DH(Diffie-Hellman算法，密钥一致协议)
 *    DSA(Digital Signature Algorithm，数字签名)
 *    ECC(Elliptic Curves Cryptography，椭圆曲线密码编码学)
 *    
 * 本篇内容简要介绍BASE64、MD5、SHA、HMAC几种方法。
 *    MD5、SHA、HMAC这三种加密算法，可谓是非可逆加密，就是不可解密的加密方法。
 *    通常只把他们作为加密的基础。单纯的以上三种的加密并不可靠。 
 *    
 * @author MIAO
 * Created on 2011-11-6
 * For more information, please visit:ismiao.com
 */
package com.ismiao.java.Encrypt;

import java.security.MessageDigest;

import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

/**
 * 基础加密组件
 */
public class Coder {
	public static final String KEY_SHA = "SHA";
	public static final String KEY_MD5 = "MD5";

	/**
	 * MAC算法可选以下多种算法
	 * 
	 * <pre>
	 * HmacMD5  
	 * HmacSHA1  
	 * HmacSHA256  
	 * HmacSHA384  
	 * HmacSHA512
	 * </pre>
	 */
	public static final String KEY_MAC = "HmacMD5";

	/**
	 * BASE64解密
	 * 
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static byte[] decryptBASE64(String key) throws Exception {
		return (new BASE64Decoder()).decodeBuffer(key);
	}

	/**
	 * BASE64加密
	 * 
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static String encryptBASE64(byte[] key) throws Exception {
		return (new BASE64Encoder()).encodeBuffer(key);
	}

	/**
	 * MD5加密 ---MD5(Message Digest algorithm 5，信息摘要算法)
	 * 
	 * @param data
	 * @return
	 * @throws Exception
	 */
	public static byte[] encryptMD5(byte[] data) throws Exception {

		MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);
		md5.update(data);

		return md5.digest();

	}

	/**
	 * SHA加密 ---Secure Hash Algorithm，安全散列算法
	 * 数字签名等密码学应用中重要的工具，被广泛地应用于电子商务等信息安全领域。 虽然，SHA与MD5通过碰撞法都被破解了，
	 * 但是SHA仍然是公认的安全加密算法，较之MD5更为安全。
	 * 
	 * @param data
	 * @return
	 * @throws Exception
	 */
	public static byte[] encryptSHA(byte[] data) throws Exception {

		MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
		sha.update(data);

		return sha.digest();

	}

	/**
	 * 初始化HMAC密钥
	 * 
	 * @return
	 * @throws Exception
	 */
	public static String initMacKey() throws Exception {
		KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);

		SecretKey secretKey = keyGenerator.generateKey();
		return encryptBASE64(secretKey.getEncoded());
	}

	/**
	 * HMAC加密
	 * 
	 * @param data
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static byte[] encryptHMAC(byte[] data, String key) throws Exception {

		SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), KEY_MAC);
		Mac mac = Mac.getInstance(secretKey.getAlgorithm());
		mac.init(secretKey);

		return mac.doFinal(data);

	}
}
